package com.csu.controller;


import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import com.csu.common.CommonResponse;
import com.csu.entity.Exam;
import com.csu.entity.Subject;
import com.csu.service.ExamGradeService;
import com.csu.service.ExamService;
import com.csu.service.SubjectService;
import com.csu.service.serviceImpl.RedisConnection;
import com.csu.vo.ExamGradeVo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

import java.util.List;

@RestController
@RequestMapping("/exams")
public class ExamController {
    //缓存键值对过期时间（毫秒）
    private static final long duration = 300000L;
    private static final ObjectMapper mapper = new ObjectMapper();

    @Autowired
    private ExamGradeService examGradeService;
    @Autowired
    private ExamService examService;
    @Autowired
    private SubjectService subjectService;

    //查询本班学生成绩信息
    @GetMapping("/{examId}/{userId}")
    //@SaCheckRole("teacher")
    public CommonResponse<List<ExamGradeVo>> getAllExamGrade(@PathVariable("examId") int exam_id, @PathVariable("userId") int user_id) throws JsonProcessingException {
        //初始化连接池，获取jedis
        RedisConnection.init();
        Jedis jedis = RedisConnection.getJedis();
        //尝试从缓存中获取
        String jsonFromRedis = jedis.get("AllStudentsGradeExamId" + exam_id + "userId" + user_id);
        if(!(jsonFromRedis == null || jsonFromRedis.isEmpty())){
            //获取到则进行序列化，然后直接返回
            List<ExamGradeVo> ExamListFromRedis = mapper.readValue(jsonFromRedis, new TypeReference<List<ExamGradeVo>>() {});
            RedisConnection.close(jedis);
            return CommonResponse.createForSuccess("SUCCESS", ExamListFromRedis);
        }
        //未获取到则正常查询
        List<ExamGradeVo> examGradeVos = examGradeService.getAllGradeOfStudent(exam_id, user_id);
        if (!examGradeVos.isEmpty()) {
            //进行反序列化
            String json = mapper.writeValueAsString(examGradeVos);
            jedis.set("AllStudentsGradeExamId" + exam_id + "userId" + user_id, json, new SetParams().px(duration));
            RedisConnection.close(jedis);
            return CommonResponse.createForSuccess("SUCCESS", examGradeVos);
        }
        else {
            RedisConnection.close(jedis);
            return CommonResponse.createForSuccess();
        }
    }

    //查询一个学生的成绩信息
    @GetMapping("/{examId}")
    //@SaCheckRole(value = {"student", "parent"}, mode = SaMode.OR)
    public CommonResponse<List<ExamGradeVo>> getOneExamGrade(@RequestParam("userId") int user_id,@PathVariable("examId") int exam_id) throws JsonProcessingException {
        //初始化连接池，获取jedis
        RedisConnection.init();
        Jedis jedis = RedisConnection.getJedis();

        String jsonFromRedis = jedis.get("studentGradeExamId" + exam_id);
        if (!(jsonFromRedis == null || jsonFromRedis.isEmpty())){
            //若从缓存中查找到，则直接返回
            List<ExamGradeVo> gradeListFromRedis = mapper.readValue(jsonFromRedis, new TypeReference<List<ExamGradeVo>>() {});
            RedisConnection.close(jedis);
            return CommonResponse.createForSuccess("SUCCESS", gradeListFromRedis);
        }

        List<ExamGradeVo> examGradeVos = examGradeService.getOneGradeOfStudent(exam_id, user_id);
        if (!examGradeVos.isEmpty()) {
            //若未从缓存中找到，则正常返回，然后存入缓存
            String json = mapper.writeValueAsString(examGradeVos);
            jedis.set("studentGradeExamId" + exam_id, json, new SetParams().px(duration));
            RedisConnection.close(jedis);
            return CommonResponse.createForSuccess("SUCCESS", examGradeVos);
        }
        else{
            RedisConnection.close(jedis);
            return CommonResponse.createForError("未找到此考试的成绩！");
        }
    }

    //获取考试列表
    @GetMapping("")
    //@SaCheckRole(value = {"student", "teacher", "parent"}, mode = SaMode.OR)
    public CommonResponse<List<Exam>> getExamList() throws JsonProcessingException {
        RedisConnection.init();
        Jedis jedis = RedisConnection.getJedis();

        String jsonFromRedis = jedis.get("exams");
        if(!(jsonFromRedis == null || jsonFromRedis.isEmpty())){
            List<Exam> examsFromRedis = mapper.readValue(jsonFromRedis, new TypeReference<List<Exam>>() {});
            RedisConnection.close(jedis);
            System.out.println("从缓存中获取成功");
            return CommonResponse.createForSuccess("SUCCESS", examsFromRedis);
        }

        List<Exam> exams = examService.getAllExam();
        if (!exams.isEmpty()) {
            String json = mapper.writeValueAsString(exams);
            jedis.set("exams", json, new SetParams().px(duration));
            RedisConnection.close(jedis);
            System.out.println("从缓存中获取失败， 已存入缓存");
            return CommonResponse.createForSuccess("SUCCESS", exams);
        }
        else {
            RedisConnection.close(jedis);
            return CommonResponse.createForError("未获取到考试信息！");
        }
    }

    //获取学科列表
    @GetMapping("/subjects/{examId}")
    //@SaCheckRole(value = {"student", "teacher", "parent"}, mode = SaMode.OR)
    public CommonResponse<List<Subject>> getSubjectListOfExam(@PathVariable("examId") int exam_id) throws JsonProcessingException {
        RedisConnection.init();
        Jedis jedis = RedisConnection.getJedis();

        String jsonFromRedis = jedis.get("subjectsExamId" + exam_id);
        if(!(jsonFromRedis == null || jsonFromRedis.isEmpty())){
            List<Subject> subjectListFromRedis = mapper.readValue(jsonFromRedis, new TypeReference<List<Subject>>() {});
            RedisConnection.close(jedis);
            System.out.println("从缓存中读取数据成功");
            return CommonResponse.createForSuccess("SUCCESS", subjectListFromRedis);
        }

        List<Subject> subjects = subjectService.getSubjectByExam(exam_id);
        if (!subjects.isEmpty()) {
            String json = mapper.writeValueAsString(subjects);
            jedis.set("subjectsExamId" + exam_id, json, new SetParams().px(duration));
            RedisConnection.close(jedis);
            System.out.println("从缓存中读取数据失败，已存入缓存");
            return CommonResponse.createForSuccess("SUCCESS", subjects);
        }
        else {
            RedisConnection.close(jedis);
            return CommonResponse.createForError("未查到与此考试相关的学科信息!");
        }
    }
}
